package util;

/**
 * <pre>
 * 
 * public void method() {
 *     Threshold threshold = mbean.start();
 *     try {
 *         ...
 *         threshold.succeeded();
 *     } finally {
 *         threshold.stop();
 *     }
 * }
 * 
 * <pre>
 * 
 * @author Mykhaylo Adamovych
 */
public class StatMBeanImpl implements StatMBean {
    public static final class Threshold {
        private StatMBeanImpl mbean;
        private Long threshold = System.currentTimeMillis();
        
        private Threshold(StatMBeanImpl mbean) {
            this.mbean = mbean;
        }
        
        public void succeeded() {
            mbean.successfullCount++;
        }
        
        public void stop() {
            long processingTime = System.currentTimeMillis() - threshold;
            mbean.totalCount++;
            if (processingTime < mbean.minTimeMs || mbean.minTimeMs == 0)
                mbean.minTimeMs = processingTime;
            if (processingTime > mbean.maxTimeMs)
                mbean.maxTimeMs = processingTime;
            mbean.totalTimeMs += processingTime;
        }
    }
    
    private volatile long totalCount;
    private volatile long totalTimeMs;
    private volatile long successfullCount;
    private volatile long minTimeMs;
    private volatile long maxTimeMs;
    
    @Override
    public long getTotalCount() {
        return totalCount;
    }
    
    @Override
    public long getSuccessfullCount() {
        return successfullCount;
    }
    
    @Override
    public long getMinTimeMs() {
        return minTimeMs;
    }
    
    @Override
    public long getMaxTimeMs() {
        return maxTimeMs;
    }
    
    @Override
    public long getAverageTimeMs() {
        return totalTimeMs / totalCount;
    }
    
    public Threshold start() {
        return new Threshold(this);
    }
}
